package com.qianfeng.websocket.handler;

//
//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖镇楼                  BUG辟易  
//          佛曰:  
//                  写字楼里写字间，写字间里程序员；  
//                  程序人员写程序，又拿程序换酒钱。  
//                  酒醒只在网上坐，酒醉还来网下眠；  
//                  酒醉酒醒日复日，网上网下年复年。  
//                  但愿老死电脑间，不愿鞠躬老板前；  
//                  奔驰宝马贵者趣，公交自行程序员。  
//                  别人笑我忒疯癫，我笑自己命太贱；  
//  


import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Jackiechan on 2022/1/5/16:42
 *
 * @author Jackiechan
 * @version 1.0
 * @since 1.0
 */
@Component
public class MyTextHandler extends TextWebSocketHandler {

    private ObjectMapper objectMapper = new ObjectMapper();
    //保存所有会话的集合
    private static Map<String, WebSocketSession> allClients = new HashMap<>();


    /**
     * 建立连接之后
     * @param session 当前建立连接的会话连接
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        URI uri = session.getUri();//我们约定uri中的最后一位是唯一标识
        System.err.println("建立连接了"+ uri);
        //按照后面的逻辑来看,这里我们需要把会话保存起来,并且还得方便单个查询,比如我要找张三的会话
        //我们怎么知道这个链接是谁的
        String uriString = uri.toString();
        String id = uriString.substring(uriString.lastIndexOf("/") + 1);
        session.getAttributes().put("name", id);//把用户的id保存到属性域中,方便下次获取,以免每次都是裁减字符串
        WebSocketSession current = allClients.get(id);//看看当前用户有没有登陆过
        if (current != null) {
            current.close();
        }
        allClients.put(id, session);//保存起来了,用户的会话
        super.afterConnectionEstablished(session);
    }


    /**
     * 处理文本消息
     * @param session 正在向我们发送数据的连接
     * @param message
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();//消息的内容
        //System.err.println("收到客户端发来的消息:" + message.getPayload());
        //session.sendMessage(new TextMessage("老王对小美说: 在有生的瞬间能遇到你,竟花光所有运气,到今日才发现,曾呼吸过空气"));
        //获取到别人的会话才能把数据转过去,想要获取别的数据就必须先把别的数据保存起来
        //现在我们模拟一个聊天的功能, 张三要给李四发消息, 我们需要知道发给谁,发的内容是什么
        //我们约定传递一个json过来,  toUser代表接收者,  msg代表消息
        //解析json,获取到接收者和内容
        //根据接收者的id 去allClients 获取到它的会话
        //如果会话存在并且是打开的状态,就把数据发过去


        Map map = objectMapper.readValue(payload, Map.class);
        String toUser = (String) map.get("toUser");//获取到接收者
        String msg = (String) map.get("msg");//获取到消息

        WebSocketSession toSession = allClients.get(toUser);
        if (toSession != null&&toSession.isOpen()) {
            toSession.sendMessage(new TextMessage("收到来自>"+session.getAttributes().get("name")+"的消息,内容是==>"+msg));
        }
        super.handleTextMessage(session, message);
    }
//ping pong

    /**
     * 处理出现错误
     * @param session 出现错误的会话连接
     * @param exception
     * @throws Exception
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        System.err.println("出现异常");
        super.handleTransportError(session, exception);
    }

    /**
     * 当websocket的连接关闭
     * @param session
     * @param status
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        System.err.println("连接关闭了");
        super.afterConnectionClosed(session, status);
    }
}
